#include "dvHistogram.h"
#include <qwt_plot_curve.h>
#include <qwt_interval_symbol.h>
#include <qwt_symbol.h>
#include <qwt_legend.h>
#include <qwt_legend_item.h>
#include <qwt_plot_canvas.h>
#include <qwt_scale_div.h>
#include <qwt_scale_draw.h>
#include <qwt_curve_fitter.h>
#include <qwt_plot_histogram.h>
#include <qwt_column_symbol.h>
#include <qwt_scale_widget.h>
#include <QDate>

#define BAR_ALPHA_UNCHECKED 180
#define BAR_ALPHA_CHECKED   255

class Histogram: public QwtPlotHistogram
{
public:
    Histogram(const QString &, const QColor &);

    void setColor(const QColor &);
    void setValue(uint x, const double y);
};

Histogram::Histogram(const QString &title, const QColor &symbolColor):
    QwtPlotHistogram(title)
{
    setStyle(QwtPlotHistogram::Columns);

    setColor(symbolColor);
}

void Histogram::setColor(const QColor &symbolColor)
{
    QColor color = symbolColor;

    setPen(QPen(Qt::black));
    setBrush(QBrush(color));

    QwtColumnSymbol *symbol = new QwtColumnSymbol(QwtColumnSymbol::Box);
    symbol->setFrameStyle(QwtColumnSymbol::Raised);
    symbol->setLineWidth(2);
    symbol->setPalette(QPalette(color));
    setSymbol(symbol);
}

void Histogram::setValue(uint x, const double y)
{
    QVector<QwtIntervalSample> samples;
    QwtInterval interval(double(x), x + 1.0);
    interval.setBorderFlags(QwtInterval::ExcludeMaximum);
    samples.push_back(QwtIntervalSample(y, interval));
    setData(new QwtIntervalSeriesData(samples));
}

dvHistogram::dvHistogram(QWidget *parent) :
    QwtPlot(parent), dvDatabaseControllerUsable()
{
    m_showLegend = true;
    showLegend(m_showLegend);

    enableAxis(QwtPlot::xBottom, false);

    canvas()->setPalette(Qt::white);
    canvas()->setBorderRadius(5);
    canvas()->setCursor(Qt::ArrowCursor);

    connect(this, SIGNAL(legendChecked(QwtPlotItem *, bool)),
        SLOT(showItem(QwtPlotItem *, bool)));

    setAutoReplot(true);
}

dvHistogram::~dvHistogram()
{
    if (m_pLegend) delete m_pLegend;
}

void dvHistogram::clear()
{
    setTitle("");
    setAxisScaleDiv(QwtPlot::xBottom, QwtScaleDiv());
    setAxisScaleDraw(QwtPlot::xBottom, new QwtScaleDraw);
    setAxisScale(QwtPlot::xBottom,0,1000);
    setAxisScale(QwtPlot::yLeft,0,1000);
    setAxisScaleDraw(QwtPlot::xBottom, new QwtScaleDraw);

    foreach(Histogram* bar, m_bars.values())
    {
        if (bar)
        {
            bar->detach();
            delete bar;
        }
    }

    m_bars.clear();
    m_barsValues.clear();
    m_barsColors.clear();
    m_barsAttached.clear();

    if (m_showLegend)
    {
        showLegend(false);
        m_showLegend = true;
    }
    else
        showLegend(false);
}

void dvHistogram::showLegend(bool show)
{
    m_showLegend = show;
    if (show)
    {
        m_pLegend = new QwtLegend();
        m_pLegend->setItemMode(QwtLegend::CheckableItem);
        insertLegend(m_pLegend, QwtPlot::RightLegend);
        setCheckedItemsLegend();
    }
    else
    {
        insertLegend(NULL, QwtPlot::RightLegend);
        m_pLegend = NULL;
    }
}

void dvHistogram::insertBar(int region, double value, QColor &color, bool attached)
{
    if (m_dbCtrl)
    {
        color.setAlpha(BAR_ALPHA_UNCHECKED);
        QString title = m_dbCtrl->getRegionName(QVariant(region)).toString();
        Histogram *hist = new Histogram(title, color);
        hist->setValue(m_bars.count(), value);
        m_bars.insert(region, hist);
        m_barsValues.insert(region, value);
        m_barsColors.insert(region, color);
        m_barsAttached.insert(region, true);
        if (attached) hist->attach(this);
    }
}

void dvHistogram::removeBar(int region)
{
    Histogram *hist = m_bars.value(region, NULL);
    if (hist)
    {
        hist->detach();
        delete hist;
        m_bars.remove(region);
        m_barsValues.remove(region);
        m_barsColors.remove(region);
        m_barsAttached.remove(region);
    }
}

void dvHistogram::rebuildHistogram()
{
    foreach(Histogram* bar, m_bars.values())
    {
        if (bar)
        {
            bar->detach();
            delete bar;
        }
    }
    m_bars.clear();

    int i = 0;
    foreach(int region, m_barsValues.keys())
    {
        QString title = m_dbCtrl->getRegionName(QVariant(region)).toString();
        Histogram *hist = new Histogram(title, m_barsColors.value(region, QColor(Qt::white)));
        if (m_barsAttached.value(region))
        {
            hist->setValue(i, m_barsValues.value(region));
            hist->attach(this);
            i++;
        }
        else
        {
            hist->setValue(m_bars.count(), m_barsValues.value(region));
        }
        m_bars.insert(region, hist);
    }
    replot();
}

void dvHistogram::showBar(int region, bool show)
{
    Histogram *hist = m_bars.value(region, NULL);
    if (hist)
    {
        if (show)
        {
            hist->attach(this);
            m_barsAttached.insert(region, true);
        }
        else
        {
            hist->detach();
            m_barsAttached.insert(region, false);
        }
    }
    rebuildHistogram();
    showLegend(m_showLegend);
}

void dvHistogram::setHiddenAllBars(bool hidden)
{
    foreach(int region, m_bars.keys())
    {
        Histogram *hist = m_bars.value(region, NULL);
        if (hist)
        {
            if (!hidden)
            {
                hist->attach(this);
                m_barsAttached.insert(region, true);
            }
            else
            {
                hist->detach();
                m_barsAttached.insert(region, false);
            }
        }
    }
    rebuildHistogram();
    if (!hidden)
        showLegend(m_showLegend);
    else if (m_showLegend)
    {
        showLegend(false);
        m_showLegend = true;
    }
    else
        showLegend(false);
}

void dvHistogram::setCheckedItemsLegend()
{
    foreach(Histogram* hist, m_bars.values())
    {
        if (hist)
        {
            int region = m_bars.key(hist, 0);
            if (region)
            {
                QColor color = m_barsColors.value(region);
                QwtLegendItem *item = qobject_cast<QwtLegendItem*>(m_pLegend->find(hist));
                if (item)
                {
                    item->setItemMode(QwtLegend::CheckableItem);
                    if (color.alpha() == BAR_ALPHA_CHECKED)
                    {
                        item->setChecked(true);
                    }
                    else
                    {
                        item->setChecked(false);
                    }
                }
            }
        }
    }
}

int dvHistogram::barCount()
{
    return m_barsValues.count();
}

void dvHistogram::showItem(QwtPlotItem *item, bool on)
{
    Histogram* hist = dynamic_cast<Histogram*>(item);
    if (hist)
    {
        int region = m_bars.key(hist, 0);
        if (region)
        {
            QColor color = m_barsColors.value(region);
            if (on)
            {
                color.setAlpha(BAR_ALPHA_CHECKED);
                hist->setColor(color);
                m_barsColors.insert(region, color);
            }
            else
            {
                color.setAlpha(BAR_ALPHA_UNCHECKED);
                hist->setColor(color);
                m_barsColors.insert(region, color);
            }
        }
    }
}





































